<?php

	define("MODULES_PATH", ROOT."/modules/");
	define("THEMES_PATH",ROOT."/themes/");
	define("EBUILDY_PATH",ROOT."/ebuildy/");
	
	define("THEMES_URL","/themes/");
		
	define("FOLDER_MODEL","m");
	define("FOLDER_VIEW","v");
	define("FOLDER_CONTROLLER","c");
	
	define("MODULE_FILE_PAGE","Page");
	define("MODULE_FILE_COMPONENT","Component");
	define("MODULE_FILE_SKIN","Skin");
	define("MODULE_FILE_MODEL","Model");
	define("MODULE_FILE_TABLE","Table");
	define("MODULE_FILE_VO","VO");
	define("MODULE_FILE_COMMAND","Command");
	define("MODULE_FILE_FILTER","Filter");

	include_once("interface/ICommand.php");
	include_once("interface/IFilter.php");
	include_once("interface/IEvent.php");
	//include_once("interface/IDataSource.php");
	include_once("interface/ICRUDModel.php");
	include_once("interface/IModel.php");
		
	include_once("class/Event.php");
	include_once("class/EbRequest.php");
	include_once("class/EbResponse.php");
	
	include_once("class/EbSQLModel.php");
	include_once("class/EbModel.php");
	
	include_once("class/EbController.php");
	include_once("class/EbSession.php");
	include_once("class/EbView.php");
	include_once("class/EbToolkit.php");
	include_once("class/EbDebug.php");
			
	function __autoload($className)
	{		
		if ($className[0] == 'E' && $className[1] == 'b' && file_exists(EBUILDY_PATH.'class/'.$className.'.php'))
		{
			eb_include_class($className);
			return ;
		}

		$a = strpos($className,'_');
					
		if ($a != -1)
		{
			$module = substr($className,0,$a);	
			
			if (file_exists(MODULES_PATH.$module.'/'.$className.'.php'))
			{
				include_once(MODULES_PATH.$module.'/'.$className.'.php');
				return ;
			}
		}
		
		throw new Exception("<br><h2>The class '$className' is not found or the file is not included!</h2><br>");
		die();
		
		$path = str_ireplace('_', '/', $className);
	}
		
	function eb_simple_preg_match($a,$b,&$m = null)
	{
		if (strlen($b) == 0)
		{
			$b = " ";
		}
	
		$a = preg_replace("/{(\w+)}/","*",$a);
		$a = str_replace(".","\.",$a);
		$a = str_replace("/","\\/",$a);
		$a = str_replace("*","([^.]+)",$a);
		//echo "preg_match('$a','$b')<br />";
		return preg_match("/$a$/i",$b,$m);
	}
	
	function eb_get_configuration()
	{
		return EbuildyWebSite::getInstance()->config;
	}
	
	function eb_execute_command($module, $command, $data)
	{
		EbuildyControler::getInstance()->dispatchEvent(new Event($module,$command,$data));
	}
		
	function eb_include_fragment($id)
	{
		return EbView::includeFragment($id);
	}
	
	/**
	* Ebuildy Framework Utils
	*/
	function eb_include_interface($name)
	{
		if (strpos($name,".php") == 0)
		{
			$name = $name.".php";
		}
	
		include_once(EBUILDY_PATH."interface/".$name);
	}
	
	function eb_include_class($name)
	{
		if (strpos($name,".php") == 0)
		{
			$name = $name.".php";
		}
	
		include_once(EBUILDY_PATH."class/".$name);
	}	
	
	/**
	* Module File Factory implementation
	*/
	function eb_get_module_file_params($args)
	{
		$result = array();
		$listFileTypes = array(MODULE_FILE_TABLE,MODULE_FILE_MODEL,MODULE_FILE_VO,MODULE_FILE_COMMAND,MODULE_FILE_FILTER,MODULE_FILE_TABLE,MODULE_FILE_COMPONENT,MODULE_FILE_PAGE);
		
		if (count($args) >= 3)
		{
			$module = $args[0];
			$name = $args[1];
			$type = $args[2];
			$data = count($args) > 3 ? $args[3] : null;
		}
		else
		{
			// eg: "module/fileVO" or "module/fileModel.php"
			$buffer = $args[0];
			$data = count($args) > 1 ? $args[1] : null;
			
			if (strpos($buffer,".") > 0)
			{
				$buffer = substr($buffer,0,strpos($buffer,"."));
			}
						
			if (strpos($buffer,"/") > 0)
			{
				$module = substr($buffer,0,strpos($buffer,"/"));
				$name = substr($buffer,strpos($buffer,"/")+1);
				$type = "";
				
				foreach ($listFileTypes AS $item)
				{
					if (substr($name,strlen($name) - strlen($item)) == $item)
					{
						$type = $item;
						$name = substr($name,0,strlen($name) - strlen($item));
						break;
					}
				}
			}
		}
				
		if (strlen($type) == 0)
		{
			return null;
		}
		else
		{
			$result["module"] = $module;
			$result["name"] = $name;
			$result["type"] = $type;
			$result["data"] = $data;

			return $result;
		}
	}	
		
	function eb_include_module_file()
	{
		$args = eb_get_module_file_params(func_get_args());
				
		if (file_exists(eb_module_file($args['module'],$args ['name'],$args['type'])))
		{
			if (!is_null($args['data']))
			{
				extract($args['data'],EXTR_PREFIX_SAME,"_");
			}
			
			include_once(eb_module_file($args['module'],$args ['name'],$args['type']));
		}
		else
		{
			throw new Exception("Cannot include <b>".$args['type']."</b> : <b>".$args ['name']."</b> of the module <b>".$args['module']."</b>:<br /><i>".eb_module_file($args['module'],$args ['name'],$args ['type'])."</i>");
		}
	}
	
	function eb_get_module_file_vo()
	{
		$args = eb_get_module_file_params(func_get_args());
		
		return new ModuleFileVO($args["module"],$args["name"],$args["type"]);
	}
		
	function eb_module_file()
	{
		$args = eb_get_module_file_params(func_get_args());
	
		$folder = "";
	
		if ($args['type'] == MODULE_FILE_MODEL || $args['type'] == MODULE_FILE_VO || $args["type"] == MODULE_FILE_TABLE)
		{
			$folder = FOLDER_MODEL;
		}
		else if ($args['type'] == MODULE_FILE_COMMAND || $args['type'] == MODULE_FILE_FILTER)
		{
			$folder = FOLDER_CONTROLLER;
		}
		else
		{
			$folder = FOLDER_VIEW;
		}
		
		$args['name'] = strtoupper(substr($args['name'],0,1)).substr($args['name'],1);
		$args['module'] = strtoupper(substr($args['module'],0,1)).substr($args['module'],1);
		
		return MODULES_PATH.$args['module']."/".$folder."/".$args['name'].$args['type'].".php";
	}
		
	function eb_module_file_new_instance()
	{
		$args = eb_get_module_file_params(func_get_args());
		
		eb_include_module_file($args['module'],$args['name'],$args['type']);
		
		$reflectionClass = new ReflectionClass($args['name'].$args['type']);
		
		return $reflectionClass->newInstance();
	}	
	
	function eb_widget($name,$data,$echo = true)
	{
		EbView::widget($name,$data,$echo);
	}	
	
	function eb_include_component($module,$name,$data = null)
	{	
		return EbView::includeComponent($module,$name,$data);
	}
	
	function eb_get_model($module,$name)
	{
		return EbModel::getModel($module,$name);
	}
	
	function include_safe($file, $errorMessage)
	{
		if (file_exists($file))
		{
			include_once ($file);
		}
		else
		{
			throw new Exception($errorMessage);
		}
	}
	
	/**
	 * @brief Generates a Universally Unique IDentifier, version 4.
	 *
	 * This function generates a truly random UUID. The built in CakePHP String::uuid() function
	 * is not cryptographically secure. You should uses this function instead.
	 *
	 * @see http://tools.ietf.org/html/rfc4122#section-4.4
	 * @see http://en.wikipedia.org/wiki/UUID
	 * @return string A UUID, made up of 32 hex digits and 4 hyphens.
	*/
    function eb_uuid() 
	{
        $pr_bits = null;
        $fp = @fopen('/dev/urandom','rb');
		
        if ($fp !== false) 
		{
            $pr_bits .= @fread($fp, 16);
            @fclose($fp);
        }
		else 
		{
            // If /dev/urandom isn't available (eg: in non-unix systems), use mt_rand().
            $pr_bits = "";
            
			for($cnt=0; $cnt < 16; $cnt++)
			{
                $pr_bits .= chr(mt_rand(0, 255));
            }
        }
      
        $time_low = bin2hex(substr($pr_bits,0, 4));
        $time_mid = bin2hex(substr($pr_bits,4, 2));
        $time_hi_and_version = bin2hex(substr($pr_bits,6, 2));
        $clock_seq_hi_and_reserved = bin2hex(substr($pr_bits,8, 2));
        $node = bin2hex(substr($pr_bits,10, 6));
      
        $time_hi_and_version = hexdec($time_hi_and_version);
        $time_hi_and_version = $time_hi_and_version >> 4;
        $time_hi_and_version = $time_hi_and_version | 0x4000;
      
        $clock_seq_hi_and_reserved = hexdec($clock_seq_hi_and_reserved);
        $clock_seq_hi_and_reserved = $clock_seq_hi_and_reserved >> 2;
        $clock_seq_hi_and_reserved = $clock_seq_hi_and_reserved | 0x8000;
      
        return sprintf('%08s-%04s-%04x-%04x-%012s',$time_low, $time_mid, $time_hi_and_version, $clock_seq_hi_and_reserved, $node);
    }
	
    /**
     * Allow to generate a random string
     */
    function eb_generate_code($l = 5)
    {
    	$str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_';
    	$buffer = '';
    	
    	while($l > 0)
		{
        	$buffer .= substr($str,mt_rand(0,36),1);
        	
        	$l --;
        }
        
        return $buffer;
    }
    
	/**
	* Allow to parse a parameters String (eg: "server=localhost;login=root;")
	* @param String
	* @return Array
	*/
	function eb_parse_parameters_string($value)
	{
		if (is_array($value))
		{
			return $value;
		}
	
		$buffer = split("[= ; : ,]",$value);
		$list = array();
				
		for ($i = 0; $i < count($buffer) - 1; $i += 2)
		{
			if (strlen($buffer[$i]) > 0)
			{
				$list[$buffer[$i]] = $buffer[$i + 1];
			}
		}
		
		return $list;
	}
	
	/**
	* Return true if the string is date formatted
	*/
	function is_date( $str )
	{	
	  $stamp = @strtotime( $str );
	 
	  if (!is_numeric($stamp))
	  {
		 return FALSE;
	  }
	  $month = @date( 'm', $stamp );
	  $day   = @date( 'd', $stamp );
	  $year  = @date( 'Y', $stamp );
	 
	  if (@checkdate($month, $day, $year))
	  {
		 return TRUE;
	  }
	 
	  return FALSE;
	} 
	
	/**
	* Easy way to log in the console
	*/
	function eb_trace($message)
	{
		EbDebug::trace($message);
	}
	
	/**
	* Improved version of var_dump
	*/
	function eb_var_dump(&$varInput, $var_name='', $reference='', $method = '=', $sub = false) 
	{
		static $output ;
		static $depth ;

		if ( $sub == false ) {
			$output = '' ;
			$depth = 0 ;
			$reference = $var_name ;
			$var = serialize( $varInput ) ;
			$var = unserialize( $var ) ;
		} else {
			++$depth ;
			$var =& $varInput ;
			
		}
			
		// constants
		$nl = "<br />\n" ;
		$block = 'a_big_recursion_protection_block';
		
		$c = $depth ;
		$indent = '' ;
		while( $c -- > 0 ) {
			$indent .= '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' ;
		}

		// if this has been parsed before
		if ( is_array($var) && isset($var[$block])) {
		
			$real =& $var[ $block ] ;
			$name =& $var[ 'name' ] ;
			$type = gettype( $real ) ;
			$output .= $indent.'<b>'.$var_name.'</b> '.$method.'& '.($type=='array'?'Array':get_class($real)).' '.$name.$nl;
		
		// havent parsed this before
		} else {

			// insert recursion blocker
			$var = Array( $block => $var, 'name' => $reference );
			$theVar =& $var[ $block ] ;

			// print it out
			$type = gettype( $theVar ) ;
			switch( $type ) {
			
				case 'array' :
					$output .= $indent .'<b>'. $var_name . '</b> '.$method.' Array ('.$nl;
					$keys=array_keys($theVar);
					foreach($keys as $name) {
						$value=&$theVar[$name];
						eb_var_dump($value, $name, $reference.'["'.$name.'"]', '=', true);
					}
					$output .= $indent.')'.$nl;
					break ;
				
				case 'object' :
					$output .= $indent.'<b>'.$var_name.'</b> = '.get_class($theVar).' {'.$nl;
					foreach($theVar as $name=>$value) {
						eb_var_dump($value, $name, $reference.': '.$name, ': ', true);
					}
					$output .= $indent.'}'.$nl;
					break ;
				
				case 'string' :
					$output .= $indent .'<b>'. $var_name . '</b>  '.$method.' "'.htmlspecialchars($theVar).'"'.$nl;
					break ;
					
				default :
					$output .= $indent .'<b>'. $var_name . '</b>  '.$method.' ('.$type.') '.$theVar.$nl;
					break ;
					
			}
			
			// $var=$var[$block];
			
		}
		
		-- $depth ;
		
		if( $sub == false )
			return $output ;
	}
	
	function eb_redirect($url)
	{
		EbController::dispatchEvent(new Event('redirect',$url));
	}
	